iconEuler Examples

Depth of Field of an Ideal Lens

by R. Grothmann

In this notebook, we compute the formulas for the depth of field (DOF) of an ideal lens.

First we know the basic equation.

DOF of an ideal lens

Here f is the focal length, x is the distance of the film plane to the lens, and d is the distance of the object from the lens, all assuming that the image is sharp.

To accommodate for the so-called form factor (also called crop factor) of modern cameras, we use f/ff instead of f. Most photographers are used to 36mm film and multiply the true focal length by ff to get the equivalent focal length. If you do so, use ff=1.5 for compact SLR, and ff=5 for compact digitals.

>beq &= 1/(f/ff)=1/x+1/d
                              ff   1   1
                              -- = - + -
                              f    x   d

f is the focal length computed for 36mm. ff is the factor, such that f/ff is the true focal length. The form factor ff is 1 for 35mm (film), 1.5 for the DX format, 5 for compact digital.

In the following, x is the distance of film plane from the lens, where an object in distance d is sharp.

>&solve(beq,x); function x(d,f,ff) &= rhs(%[1])
                                 d f
                               --------
                               d ff - f

Circle of Confusion

Next we compute the radius of confusion. If a light point is mapped, its rays are within a cone behind the lens. The intersections with the film plane are circles (or ellipses off the center). The radius of the circles depend on the object distance od, the focussed distance d, the focal length f (scaled to 36mm film), the form factor ff, and the F-stop (aperture) a.

This is simple geometry. Denote by x the distance of the film to the lens (for the set distance d), and xo the focus distance of the object at distance do. Then the lens opening f/a (for ff=1) is multiplied by the factor (xo-x)/xo.

>&factor(ratsimp((x(od,f,ff)-x(d,f,ff))/x(od,f,ff)*(f/ff)/a)); ...
   function us(od,d,f,ff,a) &= %
                               2
                              f  (od - d)
                         - ------------------
                           a ff (d ff - f) od

Let us plot the radius of confusion for a 50mm lens with a form factor of 1 (film), a=8, set to a distance of d=1, for various object distances od. Clearly, the image is sharp only if od=d.

>plot2d("us(x,1,0.05,1,8)*1000",0.5,2,xl="d",yl="r (mm)",>smaller):

DOF of an ideal lens

The Depth of Field

To get the near boundary of the DOF, we solve the equation, that the diameter of blur is equal to some largest admissable diameter. For 35mm this is usually taken as c=0.03mm. But we need to multiply this by the form factor ff, since the image will be magnified by this factor.

The function dn (near distance of DOF) will depend on the set distance d, the focal length together with the form factor, the F-stop a, and the maximal accepted radius c for film.

>function dn(d,f,ff,a,c=0.00003) &= rhs(solve(us(od,d,f,ff,a)=c/ff,od)[1])
                                   2
                                d f
                        ---------------------
                                    2
                        a c d ff + f  - a c f

The same for the far end of the DOF.

>function df(d,f,ff,a,c=0.00003) &= rhs(solve(us(od,d,f,ff,a)=-c/ff,od)[1])
                                    2
                                 d f
                       - ---------------------
                                     2
                         a c d ff - f  - a c f

As an example, we compute the DOF for 50mm film at F8, when the camera is set to 1m.

>[dn(1,50mm,1,8,0.00003),df(1,50mm,1,8,0.00003)]
[0.916422,  1.10035]

We can plot the DOF for distances from 1m to 5m, 50mm film at F8.

>x=1:0.01:5; ...
 plot2d(x,dn(x,50mm,1,8)_df(x,50mm,1,8),xl="od",yl="d");

We add the DOF for a DX camera. It is much wider.

>plot2d(x,dn(x,0.05,1.5,8)_df(x,0.05,1.5,8),add=1,color=11);

And the focussed distance for reference.

The plot does also show that there is always more DOF behind the object, but not twice as much, as the rule of thumb says.

>plot2d(x,x,add=1,color=12,title="DOF at distance"):

DOF of an ideal lens

Let us make a function, which returns both ends of the DOF.

>function dof(x,f,ff,a) := [dn(x,f,ff,a),df(x,f,ff,a)];

A few examples. First a DX camera with a 18mm, 35mm, 85mm lens at F8 set to 4m of distance. A negative upper end of the interval means sharpness to infinity.

>for d=[28mm,35mm,50mm,85mm]; dof(4,d,1.5,8), end;
[1.41435,  -4.82997]
[1.84446,  -23.7173]
[2.54582,  9.32836]
[3.34313,  4.97812]

Another typical example is a midsize sensor as in the RX100 with a crop factor of 2.7. If you put this camera to F5.6 and focus on 138cm distance it will be sharp to infinity at the wide angle end.

>dof(138cm,28mm,2.7,7)
[0.693281,  145.811]

The Hyperfocal Distance

Next we compute the hyperfocal distance (HFD). This is the distance we have to focus at to get as much as possible DOF, ending at infinity.

>&solve(df(d,f,ff,a,c)=s,d);  ...
   function hfd(f,ff,a,c=0.00003) &= limit(rhs(%[1]),s,inf)
                               2
                              f  + a c f
                              ----------
                                a c ff

E.g., at 50mm film, F8, we have to focus at 10.47m.

>hfd(50mm,1,8)
10.4666666667

With a wide angle 18mm lens, we can focus much closer, and still get everything to infinity into DOF.

>hfd(18mm,1,8)
1.368

Where does the DOF start, if we use the hyperfocal distance? It is a fact that it starts at 1/2 of the HFD. As a rule, we have to focus on double the distance we want the DOF to start at.

>&ratsimp(hfd(f,ff,a,c)/dn(hfd(f,ff,a,c),f,ff,a,c))
                                  2

We now plot the HFD depending on the focal length for the DX format at F8.

>plot2d("hfd(x/1000,1.5,8)",a=18,b=120,c=0,d=50, ...
   title="HFD at focal length"):

DOF of an ideal lens

Or we can plot the HFD for 50mm on DX for various F-stops. Clearly, we need to use higher F-stops, if we want more DOF.

>plot2d("hfd(0.05,1.5,x)",a=2,b=16,c=0,d=60,title="HFD at f-stop"):

DOF of an ideal lens

Here is a typical example for a 2.7 crop factor (like the RX100) and F6.3 at its wide angle. This would be a good snapshot setting.

>hfd(28mm,2.7,6.3)
1.54672153635

Same Object with different Lenses

Assume, we want a fixed object to fill the frame. Then we need to keep the distance to the object and the focal length in a fixed proportion.

Surprisingly, the DOF is almost the same from 30mm to 150mm.

>plot2d("df(x/10,x/1000,1.5,4)-dn(x/10,x/1000,1.5,4)", ...
   a=30,b=150,c=0,d=20,title="DOF at focal length, fixed object"):

DOF of an ideal lens

However, if we do this, the blurring at infinity increases with the focal length. Since f/od is constant, it increases with the focal length. It does also increase with lower F-stops of course.

But is cheaper and more effective to increase the focal length than to buy faster lenses, if the aim is to blur the background.

>&limit(us(od,d,f,ff,a),d,inf)
                                   2
                                  f
                               --------
                                   2
                               a ff  od

We can also determine, which combinations of focal length and F-stop give 2m HFD. We do that numerically in Euler.

>fcontour("hfd(x/1000,1.5,y)",xmin=18,xmax=50,ymin=2,ymax=16,level=2, ...
   title="2m HDF at focal length and F-stop"):

DOF of an ideal lens

This can be solved by Maxima exactly.

>&solve(hfd(f,ff,a,c)=hfd,a)
                                     2
                                    f
                         [a = --------------]
                              c ff hfd - c f

Utility File

There is a utility file containing these definitions.

>load dof; help "dof.e"
Euler file C:\euler\\util\dof.e found.
File contains the following definitions:


function enddof (d, f, cf, a, c=0.00002)
## Far limit of DOF

function startdof (d, f, cf, a, c=0.00002)
## Near limit of DOF

function dof (d:real vector, f:real vector, 
## DOF interval

function hyperfocal (f, cf, a, c=0.00002)
## Hyperfocal distance

function coc (od, d, f, cf, a)
## Circle of Confusion

This version of dof() return NAN (not a number) for infinity by default.

>dof(4m,18mm,1.5,[2,4,8,16])
      2.30081       15.2975 
      1.61483           NAN 
      1.01161           NAN 
     0.579026           NAN 

Examples